package test;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.servlet.SolrRequestParsers;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import util.StringHelper;
import entity.News;
import entity.SearchResult;

public class SolrHelper {

	private static final String myServer = "http://o2tv.vn:8983/solr/";

	private static final String myCollection = "news";

	// Can be set to 'on', 'off' or 'constellio' to include Constellio's facets
	private static final String facet = "constellio";

	// q=...
	private static final String query = "open source";

	private static final int start = 0;
	private static final int nbDocuments = 11;
	private static CommonsHttpSolrServer server = null;

	private static void init() {
		if (server == null) {
			try {
				server = new CommonsHttpSolrServer(myServer);
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			server.setParser(new XMLResponseParser());
		}
	}

	public static void main(String[] args) throws SolrServerException {
		// NewsModel model = new NewsModel();
		// News n = model.all().get(0);
		// SolrHelper.add(n);
		// System.out.println("add Ok");
		search("Sát thủ", null, null, "the-gioi");
	}

	public static void add(News n) {
		init();
		Document doc = null;
		SolrInputDocument solrDoc = new SolrInputDocument();
		solrDoc.addField("url", n.getUrl());
		doc = Jsoup.parse(n.getTitle());
		if (n.getTitle() != null) {
			solrDoc.addField("title",
					StringHelper.replaceVietnamese(doc.text()));
			solrDoc.addField("titleUtf8", n.getTitle());
		}
		if (n.getDescription() != null) {
			doc = Jsoup.parse(n.getDescription());
			solrDoc.addField("description",
					StringHelper.replaceVietnamese(doc.text()));
			solrDoc.addField("descriptionUtf8", n.getDescription());
		}
		if (n.getContent() != null) {
			doc = Jsoup.parse(n.getContent());
			solrDoc.addField("content",
					StringHelper.replaceVietnamese(doc.text()));
			solrDoc.addField("contentUtf8", n.getContent());
		}
		if (n.getAuthor() != null) {
			doc = Jsoup.parse(n.getAuthor());
			solrDoc.addField("author",
					StringHelper.replaceVietnamese(doc.text()));
			solrDoc.addField("authorUtf8", n.getAuthor());
		}
		if (n.getDoc() != null) {
			solrDoc.addField("doc", n.getDoc());
		}
		if (n.getDog() != null) {
			solrDoc.addField("dog", n.getDog());
		}
		if (n.getCategory() != null) {
			solrDoc.addField("category", n.getCategory());
		}
		if (n.getSubCategory() != null) {
			solrDoc.addField("subCategory", n.getSubCategory());
		}
		if (n.getSource() != null) {
			solrDoc.addField("source", n.getSource());
		}
		if (n.getSourceName() != null) {
			solrDoc.addField("sourceName", n.getSourceName());
		}
		System.out.println(n.getTitle());
		try {
			server.add(solrDoc);
			server.commit();
			System.out.println(n.getUrl() + " is indexed !"); 
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static SearchResult search(String key, Calendar from, Calendar to,
			String cate) {
		init();
		List<News> listReturn = new ArrayList<News>();
		StringBuffer request = new StringBuffer();
		String subKey = key.replaceAll(" ", "-");
		request.append("q=titleUtf8:" + key);
		request.append("&title=" + subKey);
		request.append("&fq=descriptionUtf8=" + key);
		request.append("&description=" + subKey);
		request.append("&fq=contentUtf8=" + key);
		request.append("&content=" + subKey);
		if (cate != null) {
			request.append("&fq=category:" + cate);
		}
		if (from != null && to != null) {
			String q = "&fq=doc:[" + from.get(Calendar.YEAR) + "-"
					+ from.get(Calendar.MONTH) + "-" + from.get(Calendar.DATE)
					+ "T00:00:00Z TO " + to.get(Calendar.YEAR) + "-"
					+ to.get(Calendar.MONTH) + "-" + to.get(Calendar.DATE)
					+ "T00:00:00Z]";
			System.out.println(q);
			request.append(q);
		}
		if (from != null && to == null) {
			request.append("&fq=doc:[" + from.get(Calendar.YEAR) + "-"
					+ from.get(Calendar.MONTH) + "-" + from.get(Calendar.DATE)
					+ "T00:00:00Z TO *");
		}
		if (from == null && to != null) {
			request.append("&fq=doc:[* TO " + to.get(Calendar.YEAR) + "-"
					+ to.get(Calendar.MONTH) + "-" + to.get(Calendar.DATE)
					+ "T00:00:00Z]");
		}

		request.append("&hl=true&hl.fl=titleUtf8,descriptionUtf8");
		// request.append("&sort=dog+desc");
		SolrParams solrParams = SolrRequestParsers.parseQueryString(request
				.toString());
		System.out.println("Starting...");

		try {
			QueryResponse result = server.query(solrParams);
			SolrDocumentList list = result.getResults();
			if (list.size() > 0) {
				for (SolrDocument solrDocument : list) {
					News n = new News();
					n.setUrl((String) solrDocument.getFieldValue("url"));
					n.setAlias((String) solrDocument.getFieldValue("title"));
					n.setTitle((String) solrDocument.getFieldValue("titleUtf8"));
					n.setDescription((String) solrDocument
							.getFieldValue("descriptionUtf8"));
					n.setCategory((String) solrDocument
							.getFieldValue("category"));
					n.setDoc((Date) solrDocument.getFieldValue("doc"));

					if (result.getHighlighting().get(n.getUrl()) != null) {
						if (result.getHighlighting().get(n.getUrl())
								.get("titleUtf8") != null) {
							n.setTitle(result.getHighlighting().get(n.getUrl())
									.get("titleUtf8").toString());
						}
						if (result.getHighlighting().get(n.getUrl())
								.get("descriptionUtf8") != null) {
							n.setDescription(result.getHighlighting()
									.get(n.getUrl()).get("descriptionUtf8")
									.toString());
						}
						System.out.println(n.getTitle());
						System.out.println(n.getCategory());
					}
					listReturn.add(n);
				}
			} else {
				// request = new StringBuffer();
				// request.append("q=title:" + subKey);
				// request.append("&descriptionUtf8=" + key);
				// request.append("&description=" + subKey);
				// request.append("&contentUtf8=" + key);
				// request.append("&content=" + subKey);
				// request.append("&doc:[2010-12-31T23:59:59Z TO 2012-12-31T23:59:59Z]");
				// request.append("&hl=true&hl.fl=titleUtf8,descriptionUtf8");
				// // request.append("&sort=dog+desc");
				// solrParams = SolrRequestParsers.parseQueryString(request
				// .toString());
				// System.out.println("Starting...");
				// result = server.query(solrParams);
				// list = result.getResults();
				// for (SolrDocument solrDocument : list) {
				// News n = new News();
				// n.setUrl((String) solrDocument.getFieldValue("url"));
				// n.setAlias((String) solrDocument.getFieldValue("title"));
				// n.setTitle((String) solrDocument.getFieldValue("titleUtf8"));
				// n.setDescription((String) solrDocument
				// .getFieldValue("descriptionUtf8"));
				// n.setDoc((Date) solrDocument.getFieldValue("doc"));
				//
				// if (result.getHighlighting().get(n.getUrl()) != null) {
				// if (result.getHighlighting().get(n.getUrl())
				// .get("titleUtf8") != null) {
				// n.setTitle(result.getHighlighting().get(n.getUrl())
				// .get("titleUtf8").toString());
				// }
				// if (result.getHighlighting().get(n.getUrl())
				// .get("descriptionUtf8") != null) {
				// n.setDescription(result.getHighlighting()
				// .get(n.getUrl()).get("descriptionUtf8")
				// .toString());
				// }
				// System.out.println(n.getTitle());
				// }
				// listReturn.add(n);
				// }
			}
			SearchResult re = new SearchResult();
			re.setListNews(listReturn);
			re.setTotalResult("" + result.getResults().getNumFound());
			re.setQueryTime("" + (double) result.getQTime() / 1000);
			System.out.println(re.getQueryTime());
			System.out.println(re.getTotalResult());
			return re;

		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Do the query using a StringBuffer
	 */
	public static QueryResponse doFirstQuery(SolrServer server)
			throws SolrServerException {
		StringBuffer request = new StringBuffer();
		request.append("q=" + "title:ky-thi");
		// request.append("&cat=" + "connector");
		// request.append("&fl=" + "name,id,score,manufacturedate_dt");
		// request.append("&facet=" + facet);
		// request.append("&q=" + query);
		// request.append("&start=" + start);
		// request.append("&rows=" + nbDocuments);
		SolrParams solrParams = SolrRequestParsers.parseQueryString(request
				.toString());

		return server.query(solrParams);
	}

	/**
	 * Do the query using a ModifiableSolrParams
	 */
	public static QueryResponse doSecondQuery(SolrServer server)
			throws SolrServerException {
		ModifiableSolrParams solrParams = new ModifiableSolrParams();
		solrParams.set("collectionName", myCollection);
		solrParams.set("username", "admin");
		solrParams.set("password", "password");
		solrParams.set("facet", facet);
		solrParams.set("q", query);
		solrParams.set("start", start);
		solrParams.set("rows", nbDocuments);
		return server.query(solrParams);
	}

	/**
	 * Do the query using a SolrQuery
	 */
	public static QueryResponse doThirdQuery(SolrServer server)
			throws SolrServerException {
		SolrQuery solrQuery = new SolrQuery();
		solrQuery.setQuery(query);
		solrQuery.set("collectionName", myCollection);
		solrQuery.set("username", "admin");
		solrQuery.set("password", "password");
		solrQuery.set("facet", facet);
		solrQuery.setStart(start);
		solrQuery.setRows(nbDocuments);
		return server.query(solrQuery);
	}

	/**
	 * Do the query using a SolrQuery
	 */
	public static QueryResponse spellCheck(SolrServer server, String badQuery)
			throws SolrServerException {
		SolrQuery solrQuery = new SolrQuery();
		solrQuery.setQuery(badQuery);
		solrQuery.set("collectionName", myCollection);

		// qt=spellcheck || qt=spellchecker
		solrQuery.setQueryType("spellcheck");
		return server.query(solrQuery);
	}

	/**
	 * Print documents and facets
	 * 
	 * @param response
	 */
	@SuppressWarnings("unchecked")
	public static void print(QueryResponse response) {
		SolrDocumentList docs = response.getResults();
		if (docs != null) {
			System.out.println(docs.getNumFound() + " documents found, "
					+ docs.size() + " returned : ");
			for (int i = 0; i < docs.size(); i++) {
				SolrDocument doc = docs.get(i);
				System.out.println("\t" + doc.toString());
			}
		}

		List<FacetField> fieldFacets = response.getFacetFields();
		if (fieldFacets != null && fieldFacets.isEmpty()) {
			System.out.println("\nField Facets : ");
			for (FacetField fieldFacet : fieldFacets) {
				System.out.print("\t" + fieldFacet.getName() + " :\t");
				if (fieldFacet.getValueCount() > 0) {
					for (Count count : fieldFacet.getValues()) {
						System.out.print(count.getName() + "["
								+ count.getCount() + "]\t");
					}
				}
				System.out.println("¬ô");
			}
		}

		Map<String, Integer> queryFacets = response.getFacetQuery();
		if (queryFacets != null && !queryFacets.isEmpty()) {
			System.out.println("¬ô\nQuery facets : ");
			for (String queryFacet : queryFacets.keySet()) {
				System.out.println("\t" + queryFacet + "\t["
						+ queryFacets.get(queryFacet) + "]");
			}
			System.out.println("¬ô");
		}

		NamedList<NamedList<Object>> spellCheckResponse = (NamedList<NamedList<Object>>) response
				.getResponse().get("spellcheck");

		if (spellCheckResponse != null) {
			Iterator<Entry<String, NamedList<Object>>> wordsIterator = spellCheckResponse
					.iterator();

			while (wordsIterator.hasNext()) {
				Entry<String, NamedList<Object>> entry = wordsIterator.next();
				String word = entry.getKey();
				NamedList<Object> spellCheckWordResponse = entry.getValue();
				boolean correct = spellCheckWordResponse.get("frequency")
						.equals(1);
				System.out.println("Word: " + word + ",\tCorrect?: " + correct);
				NamedList<Integer> suggestions = (NamedList<Integer>) spellCheckWordResponse
						.get("suggestions");
				if (suggestions != null && suggestions.size() > 0) {
					System.out.println("Suggestions : ");
					Iterator<Entry<String, Integer>> suggestionsIterator = suggestions
							.iterator();
					while (suggestionsIterator.hasNext()) {
						System.out.println("\t"
								+ suggestionsIterator.next().getKey());
					}

				}
				System.out.println("¬ô");
			}

		}

	}

}